React 0 -> Hooks

0 -> Hooks

1
2
3
4
5
6
7
8
9
funcition App (){
const [num, setNum] = useState(0)

return {
onClick (){
setNum(num => num + 1)
}
}
}

React 运行环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let isMount = true  // didMount or didUpdate
let workInProgressHook = null;

const fiber = {
stateNode: App,
memoizedState: null, // 链表
queue:{ // 队列
pending: null
}
}

function schedule(){
workInProgressHook = fiber.memoizedState;
const app = fiber.stateNode();
isMount = false;
return app
}
1
window.app = schedule()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function useState(initState){
// 当前hook
let hook;

if(isMount){
hook = { // 单向链表
memoizedState: initState,
next: null // 指针 下一个
}
if(!fiber.memoizedSate){
fiber.memoizedState = hook;
}else{
workInProgressHook.next = hook
}
workInProgressHook = hook
}else{
hook = workInProgressHook;
workInProgressHook = workInProgressHook.next
}
// 取到了当前useState的数据

// todo
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function dispathAction(queue, action){
const update ={ // 环状链表
action,
next
}

if(queue.pending === null) {
// u0 -> u0 -> u0
update.next = update

}else{
// u0 -> u0
// u1 -> u0 -> u1
// queue.pending // 最后第一个
// queue.pending.next //第一个
update.next = queue.pending.next; // u1 -> u0
queue.pending.next = update; // u0 -> u1
}

queue.pending = update;

schedule();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function useState(initState){
// 当前hook
let hook;

if(isMount){
hook = { // 单向链表
memoizedState: initState,
next: null // 指针 下一个
}
if(!fiber.memoizedSate){
fiber.memoizedState = hook;
}else{
workInProgressHook.next = hook
}
workInProgressHook = hook
}else{
hook = workInProgressHook;
workInProgressHook = workInProgressHook.next
}
// 取到了当前useState的数据

let baseState = hook.memoizedState;

if(hook.queue.pending){
let firstupdate = hook.queue.pending.next;

do{
const action = firstUpdate.action
baseState = action(baseState)
firstUpdate = firstUpdate.next;
}while(firstUpdate !== hook.queue.pending.next)

hook.queue.pending = null;

}
hook.memoizedState = baseState;
return [baseState, disPatchAction.bind(null, hook.queue)]

}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
let isMount = true;
let workInProgressHook = null // 变量 当前处理哪一个hook

const fiber = {
stateNode: App,
memoizedState: null, // 保存hooks数据 一条链表 每一个hook数据
}

function schedule() {
workInProgressHook = fiber.memoizedState
const app = fiber.stateNode()
isMount = false;

return app
}


function useState(initState) {
let hook;

if (isMount) {
hook = { // 单向链表
memoizedState: initState,
next: null,
queue: {
pending: null
}
}
if (!fiber.memoizedState) {
fiber.memoizedState = hook
} else {
workInProgressHook.next = hook
}
workInProgressHook = hook
} else {
// 已经有一条链表了
hook = workInProgressHook; // 取到了
workInProgressHook = workInProgressHook.next; // 指向下一个
}
// 取到了当前useState对应的数据 ,then 计算新状态

let baseState = hook.memoizedState

if (hook.queue.pending) {
let firstUpdate = hook.queue.pending.next // 第一个update

do {
const action = firstUpdate.action
baseState = action(baseState);
firstUpdate = firstUpdate.next // 指向下一个
} while (firstUpdate != hook.queue.pending.next)

hook.queue.pending = null // 计算完 清空
}

hook.memoizedState = baseState
return [baseState, dispatchAction.bind(null, hook.queue)]
}

// setNum - action
function dispatchAction(queue, action) {
// 创建数据结构update,每次更新有优先级的,click > fecth
const update = {
action, // 环装链表
next: null
}

// 链表操作
if (queue.pending === null) {
update.next = update
} else {
// u0 -> u0
// u1 -> u0 -> u1
// queue.pending 最后一个update
// queue.pending.next 第一个update
console.log("第一个update",queue.pending.next)
console.log("最后一个update",queue.pending)
update.next = queue.pending.next; // u1 => u0
queue.pending.next = update; // u0 => u1
}
// 每次执行就是最后一个update
queue.pending = update

schedule()
}

// FC 保存hooks数据
function App() {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(10)
const [num2, setNum2] = useState(22)


console.log(isMount)
console.log("num",num)
console.log("num1",num1)
console.log("num2",num2)
console.log("----")

return {
onClick() {
setNum(num => num + 1)
},
set() {
setNum1(num => num + 10)
},
set2() {
setNum2(num => num + 10)
}
}
}

window.app = schedule()
感谢你的打赏哦!